<template>
  <div :style="{width: '100%'}">
    <div :id="dndContainer"
         :style="{display:'inline-block', background:'#151e2d', height: lastHeight + 'px',width: '15%', overflow:'auto' }">
      <el-tree
        class="containertree"
        :style="{height: lastHeight + 'px' }"
        :data="data"
        :props="defaultProps"
        default-expand-all
        ref="tree">
        <template slot-scope="{ node, data }">
          <div v-if="data.hasOwnProperty('icon')" class="drag-node" @mousedown="startDrag" style="width: 100%;">
            <svg-icon :icon-class="data.icon" />
            {{ node.label }}
          </div>
          <div v-else style="width: 100%;">
            {{ node.label }}
          </div>
        </template>
      </el-tree>
    </div>
    <div ref="containerDiv"
         :style="{position:'absolute',overflow:'auto', display:'inline-block',height: lastHeight-50 + 'px',width:'85%' }">
      <!--        <div style="position:fixed;right: 10px;top:150px;z-index: 2000;color: #99a9bf">-->
      <!--          <span  @click="zoomIn">-->
      <!--            <svg-icon style="font-size: 19px;" icon-class="zoom-in"/>-->
      <!--          </span>-->
      <!--          <span @click="zoomOut">-->
      <!--            <svg-icon style="font-size: 19px;" icon-class="zoom-out"/>-->
      <!--          </span>-->
      <!--        </div>-->
      <div :id="container">
      </div>
    </div>

    <el-dialog @close="addNode(false)" width="25%" title="新建节点" style="z-index:1000000"
               :visible.sync="dialogFormVisible">
      <el-form ref="addnodeform" :model="addnodeform" :rules="fromrules">
        <el-form-item label="节点类型：" label-width="120px">
          {{ nodetypename }}
        </el-form-item>
        <el-form-item label="路径：" label-width="120px">
          {{ flowName }}
        </el-form-item>
        <el-form-item label="名称：" label-width="120px" prop="name4">
          <el-input style="width: 90%" placeholder="请输入名称" size="mini" v-model="addnodeform.name4"
                    autocomplete="off"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button size="mini" @click="addNode(false)">取 消</el-button>
        <el-button size="mini" type="primary" @click="addNode">确 定</el-button>
      </div>
    </el-dialog>
    <el-dialog
      :title="nodeTitle"
      :visible.sync="nodedialogVisible"
      :width="dialogWidth"
      :before-close="nodehandleClose"
      :top="dialogTop"
      :close-on-click-modal=false
      class="nodeDialog"
      :onselectstart="false"
      ref="dialogref"
    >
      <el-form style="margin-left: 40px" :inline="toolTypeShow" :model="nodename">
        <el-form-item label="步骤名称" label-width="80px">
          <el-input :style="{width: inputWidth}" size="mini" v-model="nodename.name" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item v-if="toolTypeShow" label="同步工具" label-width="80px">
          <el-select filterable style="width: 520px" size="mini"
                     v-model="toolType" placeholder="请选择同步工具"
                     @change="getOffline()">
            <el-option
              v-for="item in toolTypeOption"
              :key="item.lable"
              :label="item.lable"
              :value="item.lable">
            </el-option>
          </el-select>
        </el-form-item>
      </el-form>
      <span>
            <nodeContainers v-if="nodeType==='Sync Offline'&& toolType!=='datax-shell'"
                            ref="nodeContainers"></nodeContainers>
            <datax-json v-if="nodeType==='Sync Offline'&& toolType==='datax-shell'" ref="dataxjson"></datax-json>
            <nodeSql ref="nodeSql" v-if="nodeType==='Exec Sql'"></nodeSql>
            <nodeHttp ref="nodeHttp" v-if="nodeType==='Http Request'"></nodeHttp>
            <nodeCollect ref="nodeCollect" v-if="nodeType==='Fetch Data'"></nodeCollect>
            <nodeCollectOne ref="nodeCollectOne" v-if="nodeType==='Fetch One'"></nodeCollectOne>
            <nodeCase ref="nodeCase" v-if="nodeType==='Case'"></nodeCase>
          </span>
      <span slot="footer" class="dialog-footer">
          <el-button size="mini" @click="nodehandleClose()">取 消</el-button>
           <el-button type="primary" size="mini" @click="saveNode()">确 定</el-button>
        </span>
    </el-dialog>
  </div>
</template>

<script>
import { Graph } from "@antv/x6";
import { Dnd } from "@/util/Dnd";
import { Keyboard } from "@antv/x6-plugin-keyboard";
import { Selection } from "@antv/x6-plugin-selection";
import { register } from "@antv/x6-vue-shape";
import nodeshape from "./nodeshape.vue";
import creadnode from "./nodestate";
import nodeContainers from "@/views/datadevelop/components/nodeContainers.vue";
import nodeSql from "@/views/datadevelop/components/nodesql.vue";
import nodeHttp from "@/views/datadevelop/components/nodeHttp.vue";
import nodeCollect from "@/views/datadevelop/components/nodeCollect.vue";
import nodeCollectOne from "@/views/datadevelop/components/nodeCollectOne.vue";
import nodeCase from "@/views/datadevelop/components/nodeCase.vue";
import dataxJson from "@/views/datadevelop/components/dataxJson.vue";

let uid = 0;
register({
  shape: "nodeshape",
  width: 100,
  height: 100,
  component: nodeshape
});
export default {
  name: "X6Next",
  components: { nodeSql, nodeContainers, nodeHttp, nodeCollect, nodeCollectOne, nodeCase, dataxJson },
  props: ["flowId", "flowName"],
  data() {
    var validatenodename = (rule, value, callback) => {
      const nodes = this.graph.getNodes();
      nodes.forEach((item) => {
        if (this.nodetype === item.store.data.data.nodetype && value === item.store.data.attrs.label.text) {
          callback(new Error("节点名称重复"));
        } else {
          callback();
        }
      });
    };
    return {
      dialogWidth: "70%",
      dialogTop: "10px",
      inputWidth: "90%",
      uid: uid++,
      addnodeform: {
        name4: ""
      },
      fromrules: {
        name4: [{ validator: validatenodename, trigger: "blur" },
          { required: true, message: "请输入", trigger: "blur" }
        ]
      },
      catchnode: "",//修改node名称时的节点缓存
      dialogFormVisible: false,
      data: [
        {
          id: 1,
          label: "数据集成",
          children: [{
            id: 2,
            label: "离线同步",
            myNodeType: "rect",
            icon: "di"
          }]
        },
        {
          id: 3,
          label: "数据库",
          children: [

            {
              id: 4,
              label: "执行sql",
              myNodeType: "rect",
              icon: "SQL"
            },
            {
              id: 5,
              label: "抓取数据(集合)",
              myNodeType: "rect",
              icon: "fetch"
            },
            {
              id: 8,
              label: "抓取数据(单笔)",
              myNodeType: "rect",
              icon: "fetch"
            }
          ]
        },
        {
          id: 6,
          label: "接口调用",
          children: [{
            id: 7,
            label: "http",
            myNodeType: "rect",
            icon: "http"
          }]
        },
        {
          id: 9,
          label: "通用",
          children: [
            {
              id: 8,
              label: "条件分支",
              myNodeType: "rect",
              icon: "case"
            }]
        }
      ],
      defaultProps: {
        children: "children",
        label: "label"
      },
      resolveFn: "",
      graph: null,
      icon: "",
      nodetype: "",//后台存的节点类型
      nodetypename: "",//页面展示的节点类型
      flowNodeEdge: [],
      nodeId: 0,//自定义的nodeid
      newgraph: true,//判断是不是新的流传
      nodeTitle: "",
      nodedialogVisible: false,
      nodename: {
        name: "",
        nodeId: ""
      },
      nodeType: "",
      mappingValueList: [],
      toolType: "datax-skin",
      toolTypeShow: false,
      toolTypeOption: [
        { lable: "datax-skin" },
        { lable: "datax-fast" },
        { lable: "datax-shell" }
      ],
      catchToolType: ""
    };
  },
  computed: {
    container() {
      return `container_${this.uid}`;
    },
    dndContainer() {
      return `dndContainer_${this.uid}`;
    },
    documentHeight() {
      return this.$store.getters.documentHeight;
    },
    lastHeight() {
      return this.documentHeight - 95;
    }
  },
  methods: {
    //添加一个节点
    addNode(status = true) {
      // if(status) {
      //   this.$refs.addnodeform.validate((valid) => {
      //     console.log(valid)
      // if(valid){
      this.dialogFormVisible = false;
      this.catchnode.attrs.label.text = this.addnodeform.name4;
      this.resolveFn(status);
      // }
      // }
      // )
      // }
      // else {
      //   this.dialogFormVisible = false
      //   this.resolveFn(status)
      // }

    },
    //拖拽一个节点
    startDrag(e) {
      this.nodetypename = e.target.innerText;
      let nodeIdarry = [];
      this.graph.getNodes().forEach((item) => {
        nodeIdarry.push(Number(item.id));
      });
      let uuid = "";
      nodeIdarry.length !== 0 ? uuid = Math.max(...nodeIdarry) + 1 : uuid = ++this.nodeId;
      // this.graph.getNodes().length?uuid= Number(this.graph.getNodes()[this.graph.getNodes().length-1].id)+1:uuid= this.graph.getNodes().length+1
      this.seticon(e.target.innerText);
      // console.log(e,'树结构节点信息')
      e.preventDefault();
      const rect = this.graph.createNode({
        id: uuid,
        width: 130,
        height: 30,
        shape: "nodeshape",
        data: {
          icon: this.icon,
          nodestatus: "",
          nodeopen: "true",
          nodetype: this.nodetype
        },
        attrs: {
          body: {
            stroke: "#3A3D51",
            strokeWidth: 1,
            fill: "#3A3D51",
            rx: 6,
            ry: 6
          },
          label: {
            text: e.target.innerText,
            fill: "white"
          }
        },
        ports: {
          groups: {
            bottom: {
              position: "bottom",
              attrs: {
                circle: {
                  r: 3,
                  magnet: true,
                  stroke: "#31d0c6",
                  strokeWidth: 2,
                  fill: "#fff"
                }
              }
            },
            top: {
              position: "top",
              attrs: {
                circle: {
                  r: 3,
                  magnet: true,
                  stroke: "#31d0c6",
                  strokeWidth: 2,
                  fill: "#fff"
                }
              }
            },
            left: {
              position: "left",
              attrs: {
                circle: {
                  r: 3,
                  magnet: true,
                  stroke: "#31d0c6",
                  strokeWidth: 2,
                  fill: "#fff"
                }
              }
            },
            right: {
              position: "right",
              attrs: {
                circle: {
                  r: 3,
                  magnet: true,
                  stroke: "#31d0c6",
                  strokeWidth: 2,
                  fill: "#fff"
                }
              }
            }
          },
          items: [
            {
              group: "bottom",
              args: {
                dx: 2
              }
            },
            {
              group: "top",
              args: {
                dx: 2
              }
            },
            {
              group: "left",
              args: {
                dx: 2
              }
            },
            {
              group: "right",
              args: {
                dx: 2
              }
            }
          ]
        }
      });
      if (e.target.className === "drag-node") {
        this.dnd.start(rect, e);
      }
    },
    //画线方法
    drawedg() {
      this.graph.on("node:change:position", ({ node, options }) => {
        // 获取与当前节点连接的所有边
        var _node = node;
        const edges = this.graph.getConnectedEdges(node, { inbound: true, outbound: true });
        // 获取与当前节点连接的所有节点
        const connectedNodes = [];
        edges.forEach((edge) => {
          const sourceNodeId = edge.getSourceCell().id;
          const targetNodeId = edge.getTargetCell().id;
          if (sourceNodeId !== node.id) {
            connectedNodes.push(this.graph.getCellById(sourceNodeId));
          } else if (targetNodeId !== node.id) {
            connectedNodes.push(this.graph.getCellById(targetNodeId));
          }
        });
        connectedNodes.forEach((item) => {
          //item是子节点
          const nodedge = this.graph.getConnectedEdges(node);
          const itemedgr = this.graph.getConnectedEdges(item);
          const duplicates = nodedge.filter(item1 => itemedgr.some(item2 => item1.id === item2.id));
          const nodeheight = node.getSize();
          // console.log(duplicates,'node,item之间的边')
          // console.log(this.graph.getConnectedEdges(node),'node的所有边')
          // console.log(this.graph.getConnectedEdges(item),'item的所有边')
          // console.log(item.getPorts(),'item的所有连接桩')
          // console.log(node.getPorts(),'node的所有连接桩')
          // console.log(item.getBBox().y,'item的y坐标')
          // console.log(node.getBBox().y,'node的y坐标')
          // console.log(nodeheight,'节点高高度')
          let nodepotrs = "";
          let itemports = "";
          //判断node是否为边的起点
          if (duplicates[0].getTerminal().source.cell === node.id) {
            //node为边起点
            nodepotrs = "source";
            itemports = "target";
          } else {
            //node为边终点
            nodepotrs = "target";
            itemports = "source";
          }
          //移动的节点在子节点下面时候
          if (node.getBBox().y > item.getBBox().y) {
            //节点高度重合并且移动节点在子节点右侧
            if (node.getBBox().y - item.getBBox().y < nodeheight.height && node.getBBox().x > item.getBBox().x) {
              //总是使用node的left连接子节点的right
              duplicates[0].setTerminal(itemports, { cell: item.id, port: item.port.ports[3].id });
              duplicates[0].setTerminal(nodepotrs, { cell: _node.id, port: _node.port.ports[2].id });
            }
            //节点高度重合并且移动节点在子节点左侧
            else if (node.getBBox().y - item.getBBox().y < nodeheight.height && node.getBBox().x < item.getBBox().x) {
              //总是使用node的right连接子节点的left
              duplicates[0].setTerminal(itemports, { cell: item.id, port: item.port.ports[2].id });
              duplicates[0].setTerminal(nodepotrs, { cell: _node.id, port: _node.port.ports[3].id });
            } else {
              //总是使用子节点的bottom锚点连接node的top锚点
              duplicates[0].setTerminal(itemports, { cell: item.id, port: item.port.ports[0].id });
              duplicates[0].setTerminal(nodepotrs, { cell: _node.id, port: _node.port.ports[1].id });
            }
          }
          //移动的节点在子节点上面时候
          if (node.getBBox().y < item.getBBox().y) {
            //节点高度重合并且移动节点在子节点右侧
            if (item.getBBox().y - node.getBBox().y < nodeheight.height && _node.getBBox().x > item.getBBox().x) {
              //总是使用node的left连接子节点的right
              // console.log(item,'item作用域')
              duplicates[0].setTerminal(itemports, { cell: item.id, port: item.port.ports[3].id });
              duplicates[0].setTerminal(nodepotrs, { cell: _node.id, port: _node.port.ports[2].id });
            }
            //节点高度重合并且移动节点在子节点左侧
            else if (item.getBBox().y - node.getBBox().y < nodeheight.height && node.getBBox().x < item.getBBox().x) {
              //总是使用node的right连接子节点的left
              duplicates[0].setTerminal(itemports, { cell: item.id, port: item.port.ports[2].id });
              duplicates[0].setTerminal(nodepotrs, { cell: _node.id, port: _node.port.ports[3].id });
            } else {
              duplicates[0].setTerminal(itemports, { cell: item.id, port: item.port.ports[1].id });
              duplicates[0].setTerminal(nodepotrs, { cell: _node.id, port: _node.port.ports[0].id });
            }
          }
        });

      });
    },
    //鼠标的各种事件
    nodevent() {
      const showPorts = (ports, show) => {
        for (let i = 0, len = ports.length; i < len; i = i + 1) {
          ports[i].style.visibility = show ? "visible" : "hidden";
        }
      };
      const showPorts1 = (ports, view, show) => {
        for (let i = 0, len = ports.length; i < len; i = i + 1) {
          const portView = view.findPortElem(ports[i].id);
          portView.style.visibility = show ? "visible" : "hidden";
        }
      };
      //鼠标悬浮
      this.graph.on("node:mouseenter", ({ node }) => {
        const container = document.getElementById(this.container);
        const ports1 = container.querySelectorAll(
          ".x6-port-body"
        );
        const view = this.graph.findViewByCell(node);
        const ports = node.getPorts();
        showPorts1(ports, view, true);
        // node.addTools({
        //   name: 'button-remove',
        //   args: {
        //     x: 0,
        //     y: 0,
        //     offset: { x: 170, y: 15 },
        //   },
        // })
      });
      //鼠标离开
      this.graph.on("node:mouseleave", ({ node }) => {
        const container = document.getElementById(this.container);
        const ports = container.querySelectorAll(
          ".x6-port-body"
        );
        showPorts(ports, false);
        node.removeTools();
      });
      // 鼠标显示连接桩
      this.graph.on("edge:mouseenter", ({ node, edge }) => {
        // const centerY = ( this.graph.getCellById(edge.getSourceCell().id).getBBox().y + this.graph.getCellById(edge.getTargetCell().id).getBBox().y)/2
        // const centerX = ( this.graph.getCellById(edge.getSourceCell().id).getBBox().x + this.graph.getCellById(edge.getTargetCell().id).getBBox().x)/2
        edge.addTools([{
          name: "button-remove",
          args: {
            distance: -25
          }
        }, {
          name: "source-arrowhead",
          args: {
            attrs: {
              strokeWidth: 1
            }
          }
        },
          {
            name: "target-arrowhead",
            args: {
              attrs: {
                transform: "scale(1.2)"
              }
            }
          }

        ]);
        const container = document.getElementById(this.container);
        const ports = container.querySelectorAll(
          ".x6-port-body"
        );
        showPorts(ports, true);
      });
      //鼠标移出线
      this.graph.on("edge:mouseleave", ({ edge }) => {
        edge.removeTools();
        const container = document.getElementById(this.container);
        const ports = container.querySelectorAll(
          ".x6-port-body"
        );
        showPorts(ports, false);
      });
      //删除选中元素
      this.graph.bindKey("delete", () => {
        const cells = this.graph.getSelectedCells();
        if (cells.length) {
          this.graph.removeCells(cells);
        }
      });
      //双击元素
      this.graph.on("node:dblclick", ({ e, node }) => {
        this.openode(node);
      });
      //拖拽画布
      this.graph.on("blank:mouseup", ({ e, node, view }) => {
        console.log(this.graph);
      });
      //选中线
      //   this.graph.on('edge:selected', ({ cell }) => {
      //     const view = this.graph.findViewByCell(cell);
      //     const selectStroke = 'red';  // 设置选中时的颜色
      //     const selectStrokeWidth = 3; // 设置选中时的宽度
      //     view.select(selectStroke, { strokeWidth: selectStrokeWidth });
      //   });
    },
    //双击节点打开弹窗
    openode(node) {
      this.catchToolType = "";
      this.nodedialogVisible = true;
      this.nodeType = node.store.data.data.nodetype;
      this.nodeTitle = `节点${node.store.data.attrs.label.text}信息`;
      this.nodename.name = node.store.data.attrs.label.text;
      this.nodename.nodeId = node.id;
      if (this.nodeType === "Sync Offline") {
        this.dialogWidth = "70%";
        this.inputWidth = "530px";
        this.toolTypeShow = true;
        this.dialogTop = "10px";
        this.getOffline();
      }
      if (this.nodeType === "Http Request") {
        this.dialogWidth = "50%";
        this.inputWidth = "90%";
        this.toolTypeShow = false;
        this.dialogTop = "200px";
        this.getHttp();
      }
      if (this.nodeType === "Exec Sql") {
        this.dialogWidth = "50%";
        this.inputWidth = "90%";
        this.toolTypeShow = false;
        this.dialogTop = "200px";
        this.getSql();
      }
      if (this.nodeType === "Fetch Data") {
        this.dialogWidth = "50%";
        this.inputWidth = "90%";
        this.toolTypeShow = false;
        this.dialogTop = "200px";
        this.getCollect();
      }
      if (this.nodeType === "Fetch One") {
        this.dialogWidth = "50%";
        this.inputWidth = "90%";
        this.toolTypeShow = false;
        this.dialogTop = "200px";
        this.getCollectOne();
      }
      if (this.nodeType === "Case") {
        this.dialogWidth = "50%";
        this.inputWidth = "90%";
        this.toolTypeShow = false;
        this.dialogTop = "200px";
        this.getCase();
      }
      // this.getNodeMsg()
      // this.$bus.$emit('addtabs',{data:node,type:"node",flowId:this.flowId})
      // this.$emit('addtabs',{data:node,type:"node"});
    },
    getOffline() {
      if (this.catchToolType === "" || this.catchToolType === this.toolType) {
        let querydata = {
          flowInfoId: this.flowId,
          componentSeq: this.nodename.nodeId
        };
        this.$http.post("/offlineSync/getSyncOffline", querydata).then((res) => {
          console.log(res);
          // if (res.data) {

          res.data ? (this.toolType = res.data.toolType, this.catchToolType = res.data.toolType) : this.toolType = this.catchToolType = "datax-skin", this.$refs.nodeContainers && this.$refs.nodeContainers.restForm();
          this.$nextTick(() => {
            if(this.toolType==='datax-json'){
              this.toolType = "datax-shell"
            }
            if (res.data && this.toolType === "datax-shell") {
              this.$refs.dataxjson.invertData(res.data);
            } else {
              this.$refs.nodeContainers.invertData(res.data);

            }
          });

          // }
        });
      }

    },
    getHttp() {
      let querydata = {
        flowInfoId: this.flowId,
        componentSeq: this.nodename.nodeId
      };
      this.$http.post("/httpRequest/getHttpRequest", querydata).then((res) => {
        console.log(res);
        // if (res.data) {
        this.$refs.nodeHttp.invertData(res.data);
        // }
      });
    },
    getSql() {
      let querydata = {
        flowInfoId: this.flowId,
        componentSeq: this.nodename.nodeId
      };
      this.$http.post("/execSql/getExecSql", querydata).then((res) => {
        console.log(res);
        if (res.data) {
          this.$refs.nodeSql.invertData(res.data);
        }
      });
    },
    getCollect() {
      let querydata = {
        flowInfoId: this.flowId,
        componentSeq: this.nodename.nodeId
      };
      this.$http.post("/fetchData/getFetchData", querydata).then((res) => {
        console.log(res);
        if (res.data) {
          this.$refs.nodeCollect.invertData(res.data);
        }
      });
    },
    getCollectOne() {
      let querydata = {
        flowInfoId: this.flowId,
        componentSeq: this.nodename.nodeId
      };
      this.$http.post("/fetchOne/getFetchOne", querydata).then((res) => {
        console.log(res);
        if (res.data) {
          this.$refs.nodeCollectOne.invertData(res.data);
        }
      });
    },
    getCase() {
      let querydata = {
        flowInfoId: this.flowId,
        componentSeq: this.nodename.nodeId
      };
      this.$http.post("/case/getCase", querydata).then((res) => {
        // console.log(res);
        // if (res.data) {
        this.$refs.nodeCase.invertData(res.data, this.graph.getNodes())
        ;
        // }
      });
    },
    //设置图标
    seticon(title) {
      let titlesrt = title.trim();
      if (titlesrt === "离线同步") {
        this.icon = "di";
        this.nodetype = "Sync Offline";
      }
      if (titlesrt === "执行sql") {
        this.icon = "SQL";
        this.nodetype = "Exec Sql";
      }
      if (titlesrt === "抓取数据(集合)") {
        this.icon = "fetch";
        this.nodetype = "Fetch Data";
      }
      if (titlesrt === "抓取数据(单笔)") {
        this.icon = "fetch";
        this.nodetype = "Fetch One";
      }
      if (titlesrt === "http") {
        this.icon = "http";
        this.nodetype = "Http Request";
      }
      if (titlesrt === "条件分支") {
        this.icon = "case";
        this.nodetype = "Case";
      }
    },
    //设置反显图标
    setReverseicon(data) {
      if (data.componentType === "Sync Offline") {
        return data.icon = "di";
      }
      if (data.componentType === "Fetch Data" || data.componentType === "Fetch One") {
        return data.icon = "fetch";
      }
      if (data.componentType === "Exec Sql") {
        return data.icon = "SQL";
      }
      if (data.componentType === "Http Request") {
        return data.icon = "http";
      }
      if (data.componentType === "Case") {
        return data.icon = "case";
      }
    },
    //设置节点状态
    setNodestuts(data, tag) {
      const nodes = this.graph.getNodes();
      if (nodes.length) {
        nodes.forEach((node) => {
          if (tag) {
            data.forEach(item => {
              if (item.componentSeq === node.id.toString() || item.componentSeq === node.id) {
                node.setData({
                  nodeopen: item.enable
                });
              }
            });
          } else {
            Object.keys(data).forEach((item) => {
              if (item === node.id.toString()) {
                node.setData({
                  nodestatus: data[item]
                });
              }
            });
          }


        });
      }
    },
    //设置节点名称
    setNodename(data) {
      const nodes = this.graph.getNodes();
      if (nodes.length) {
        nodes.forEach((node) => {
          if (this.nodename.nodeId === node.id.toString()) {
            node.attrs.label.text = this.nodename.name;
            node.setData({
              nodename: this.nodename.name
            });
          }
        });
      }
    },
    //获取画布上所有的节点和线
    getNodeEdge() {
      const nodes = this.graph.getNodes();
      let edges = this.graph.getEdges();
      edges.forEach((item) => {
        item.sourceNode = item.getSourceNode();// 获取源节点
        item.targetNode = item.getTargetNode();// 获取目标节点
      });
      return { nodes, edges };
    },
    getFlownode() {
      this.$http.post("/flow/getFlow", { id: this.flowId }).then((res) => {
        this.flowNodeEdge = res.data;
        let idArry = [];
        this.flowNodeEdge.components.forEach((item) => {
          idArry.push(Number(item.componentSeq));
        });
        this.nodeid = Math.max(...idArry);

        this.setNodestuts(res.data.components, "openNode");
        // console.log(res,'节点信息')
      }).finally(() => {
        this.graphaddnode(this.flowNodeEdge);
        this.graphaddedge(this.flowNodeEdge);

      });

    },
    //画布反显节点和线
    graphaddnode(data) {
      let nodeTemplate = creadnode.createdNode();
      data.components.forEach((item) => {
        nodeTemplate.position.x = Number(item.px);
        nodeTemplate.position.y = Number(item.py);
        nodeTemplate.id = item.componentSeq;
        nodeTemplate.data.nodetype = item.componentType;
        nodeTemplate.attrs.label.text = item.name;
        nodeTemplate.data.icon = this.setReverseicon(item);
        nodeTemplate.data.nodeopen = item.enable;
        this.graph.addNode(nodeTemplate);
      });
    },
    graphaddedge(data) {
      const nodes = this.graph.getNodes();
      data.relations.forEach(((item) => {
        let edgeTemplate = creadnode.createdEdge();
        edgeTemplate.id = item.seq;
        nodes.forEach((nodeitem) => {
          if (item.cmpFrom === nodeitem.id) {
            // console.log(nodeitem.getPorts(),'s连接桩id')
            nodeitem.getPorts().forEach((portitem) => {
              if (item.portFrom === portitem.group) {
                edgeTemplate.source.cell = item.cmpFrom;
                edgeTemplate.source.port = portitem.id;
              }
            });
          }
          if (item.cmpTo === nodeitem.id) {
            // console.log(nodeitem.getPorts(),'t连接桩id')
            nodeitem.getPorts().forEach((portitem) => {
              if (item.portTo === portitem.group) {
                edgeTemplate.target.cell = item.cmpTo;
                edgeTemplate.target.port = portitem.id;
              }
            });
          }
        });
        // console.log(edgeTemplate)
        const edge = this.graph.addEdge(edgeTemplate);
        edge.appendLabel({
          attrs: {
            text: {
              text: item.text
            }
          }
        });
      }));

    },
    saveNode() {
      if (this.nodeType === "Sync Offline" && this.toolType !== "datax-shell") {
        this.saveOffline();
      }
      if (this.nodeType === "Sync Offline" && this.toolType === "datax-shell") {
        this.saveDataxJson();
      }
      if (this.nodeType === "Http Request") {
        this.saveHttp();
      }
      if (this.nodeType === "Exec Sql") {
        this.saveSql();
      }
      if (this.nodeType === "Fetch Data") {
        this.saveCollect();
      }
      if (this.nodeType === "Fetch One") {
        this.saveCollectOne();
      }
      if (this.nodeType === "Case") {
        this.saveCase();
      }
    },
    saveOffline() {
      this.setNodename();
      this.getMappingValue();
      let querydata = {
        "flowInfoId": this.flowId,
        "componentSeq": this.nodename.nodeId,
        "srcDatasourceId": this.$refs.nodeContainers.dataSourceForm.dataSource,
        "targetDatasourceId": this.$refs.nodeContainers.dataSourceTo.dataSource,
        "srcTableName": this.$refs.nodeContainers.dataSourceForm.dataSourceTable,
        "targetTableName": this.$refs.nodeContainers.dataSourceTo.dataSourceTable,
        "targetPreSql": this.$refs.nodeContainers.dataSourceTo.targetPreSql,
        "targetPostSql": this.$refs.nodeContainers.dataSourceTo.targetPostSql,
        "srcWhereParam": this.$refs.nodeContainers.dataSourceForm.srcWhereParam,
        "threads": this.$refs.nodeContainers.passControl.threads,
        "maxErrorCount": this.$refs.nodeContainers.passControl.maxErrorCount,
        "maxErrorPercent": this.$refs.nodeContainers.passControl.maxErrorPercent,
        "columnList": this.mappingValueList,
        "src_id_expression": this.$refs.nodeContainers.dataSourceForm.src_id_expression,
        "src_start_id": this.$refs.nodeContainers.dataSourceForm.src_start_id,
        "name": this.nodename.name,
        "srcIdExpression": this.$refs.nodeContainers.dataSourceForm.srcIdExpression,
        "srcIdOffset": this.$refs.nodeContainers.dataSourceForm.srcIdOffset,
        "srcStartId": this.$refs.nodeContainers.dataSourceForm.srcStartId,
        "srcSchema": this.$refs.nodeContainers.dataSourceForm.schema,
        "targetSchema": this.$refs.nodeContainers.dataSourceTo.schema,
        "srcSqlText": this.$refs.nodeContainers.dataSourceForm.srcSqlText,
        "toolType": this.toolType,
        "fetchSize": this.$refs.nodeContainers.passControl.fetchSize,
        "batchSize": this.$refs.nodeContainers.passControl.batchSize,
        "batchByteSize": this.$refs.nodeContainers.passControl.batchByteSize
      };
      this.$http.post("/offlineSync/saveSyncOffline", querydata).then((res) => {
        console.log(res);

      }).finally(() => {
        this.catchToolType = this.toolType;
        this.nodedialogVisible = false;
        this.$message.success("保存成功");

      }).catch(() => {
      });

    },
    saveDataxJson() {
      this.setNodename();
      let querydata = this.$refs.dataxjson.addform;
      querydata.toolType = this.toolType;
      querydata.componentSeq = this.nodename.nodeId;
      querydata.flowInfoId = this.flowId;
      querydata.name = this.nodename.name;
      this.$http.post("/offlineSync/saveSyncOffline", querydata).then((res) => {
        // if (res.code === 200) {
        this.$message.success("保存成功");
        this.nodedialogVisible = false;
        this.$refs.dataxjson.restForm();
        // }
      }).finally(() => {
        this.catchToolType = this.toolType;
      });
    },
    saveHttp() {
      this.$refs.nodeHttp.$refs.addform.validate((valid) => {
        if (valid) {
          this.setNodename();
          let querydata = this.$refs.nodeHttp.addform;
          querydata.componentSeq = this.nodename.nodeId;
          querydata.flowInfoId = this.flowId;
          querydata.name = this.nodename.name;
          this.$http.post("/httpRequest/saveHttpRequest", querydata).then((res) => {
            // if (res.code === 200) {
            this.$message.success("保存成功");
            this.nodedialogVisible = false;
            this.$refs.nodeHttp.restForm();
            // }
          }).finally(() => {

          });
        }
      });

    },
    saveSql() {
      this.$refs.nodeSql.$refs.addform.validate((valid) => {
        if (valid) {
          this.setNodename();
          let querydata = this.$refs.nodeSql.addform;
          querydata.componentSeq = this.nodename.nodeId;
          querydata.flowInfoId = this.flowId;
          querydata.name = this.nodename.name;
          this.$http.post("/execSql/saveExecSql", querydata).then((res) => {
            // if (res.code === 200) {
            this.$message.success("保存成功");
            this.nodedialogVisible = false;
            this.$refs.nodeSql.restForm();
            // }
          }).finally(() => {

          });
        }
      });
    },
    saveCollect() {
      this.$refs.nodeCollect.$refs.addform.validate((valid) => {
        this.$refs.nodeCollect.$refs.ruleForm.validate((valid1) => {
          if (valid && valid1) {
            this.setNodename();
            let querydata = this.$refs.nodeCollect.addform;
            querydata.componentSeq = this.nodename.nodeId;
            querydata.flowInfoId = this.flowId;
            querydata.name = this.nodename.name;
            querydata.columnList = this.$refs.nodeCollect.formdata.tableData;
            this.$http.post("/fetchData/saveFetchData", querydata).then((res) => {
              // if (res.code === 200) {
              this.$message.success("保存成功");
              this.nodedialogVisible = false;
              this.$refs.nodeCollect.restForm();
              // }
            }).finally(() => {

            });
          }
        });

      });

    },
    saveCollectOne() {
      this.$refs.nodeCollectOne.$refs.addform.validate((valid) => {
        this.$refs.nodeCollectOne.$refs.ruleForm.validate((valid1) => {
          if (valid && valid1) {
            this.setNodename();
            let querydata = this.$refs.nodeCollectOne.addform;
            querydata.componentSeq = this.nodename.nodeId;
            querydata.flowInfoId = this.flowId;
            querydata.name = this.nodename.name;
            querydata.columnList = this.$refs.nodeCollectOne.formdata.tableData;
            this.$http.post("/fetchOne/saveFetchOne", querydata).then((res) => {
              // if (res.code === 200) {
              this.$message.success("保存成功");
              this.nodedialogVisible = false;
              this.$refs.nodeCollectOne.restForm();
              // }
            }).finally(() => {

            });
          }
        });

      });
    },
    saveCase() {
      this.setNodename();
      let querydata = {};
      querydata.componentSeq = this.nodename.nodeId;
      querydata.flowInfoId = this.flowId;
      querydata.name = this.nodename.name;
      querydata.routeList = this.$refs.nodeCase.tableData;
      let edges = this.graph.getEdges();
      if (edges.length > 0) {
        edges.forEach(item => {
          if (this.nodename.nodeId === item.source.cell) {
            this.graph.removeEdge(item);
          }
        });
      }
      querydata.routeList.forEach(item => {
        this.grapheaddCasedge(item);
      });
      this.$http.post("/case/saveCase", querydata).then((res) => {
        // if (res.code === 200) {
        this.$message.success("保存成功");
        this.nodedialogVisible = false;
        // }
      });
    },
    grapheaddCasedge(data) {
      let edgeTemplate = creadnode.createdEdge();
      edgeTemplate.source.cell = this.nodename.nodeId;
      const nodes = this.graph.getNodes();
      nodes.forEach((nodeitem) => {
        if (this.nodename.nodeId === nodeitem.id.toString() || this.nodename.nodeId === nodeitem.id) {
          edgeTemplate.source.port = nodeitem.port.ports[0].id;
        }
        if (data.toComponentSeq === nodeitem.id.toString() || data.toComponentSeq === nodeitem.id) {
          edgeTemplate.target.cell = nodeitem.id;
          edgeTemplate.target.port = nodeitem.port.ports[1].id;
        }
      });
      const edge = this.graph.addEdge(edgeTemplate);
      edge.appendLabel({
        attrs: {
          text: {
            text: data.remark || ""
          }
        }
      });
    },
    getMappingValue() {
      this.$bus.$emit("getMappingValue");
      this.mappingValueList = this.$refs.nodeContainers.$refs.fieldMapping.mappingValueList;
    },
    nodehandleClose() {
      if (this.$refs.nodeContainers) {
        this.$refs.nodeContainers.restForm();
      }
      if (this.$refs.dataxjson) {
        this.$refs.dataxjson.restForm();
      }
      if (this.$refs.nodeHttp) {
        this.$refs.nodeHttp.invertData();
      }
      if (this.$refs.nodeSql) {
        this.$refs.nodeSql.invertData();
      }
      if (this.$refs.nodeCollect) {
        this.$refs.nodeCollect.invertData();
      }
      if (this.$refs.nodeCollectOne) {
        this.$refs.nodeCollectOne.invertData();
      }
      this.nodedialogVisible = false;
    }
  },
  mounted() {
    console.log(this.$refs.containerDiv.clientWidth);
    const graph = this.graph = new Graph({
      container: document.getElementById(this.container),
      width: 2000,
      // width:this.$refs.containerDiv.clientWidth,
      // height: document.getElementById(this.container).clientHeight,
      height: 2000,
      background: {
        color: "#1c1b1b"
      },
      mousewheel: {
        enabled: true,
        modifiers: ["ctrl"]
      },
      // panning: true,
      translating: {
        restrict: true
      },
      interacting: {
        nodeMovable: true,
        edgeMovable: true
      },
      connecting: {
        allowBlank: false,
        snap: {
          radius: 50
        },
        connector: "smooth",
        createEdge() {
          return this.createEdge({
            attrs: {
              line: {
                stroke: "#A2B1C3",
                strokeWidth: 1,
                targetMarker: "classic"
              }
            },
            router: {
              args: {
                offset: "center"
              }
            }
          });

        }
      }
    });
    this.graph.resize(),
      this.graph.use(
        new Keyboard({
          enabled: true
        })
      ).use(
        new Selection({
          enabled: true,
          rubberband: true,
          showNodeSelectionBox: false
        })
      );
    // this.creadnode()
    const dnd = this.dnd = new Dnd({
      getDragNode: (node) => node.clone({ keepId: true }),
      getDropNode: (node) => node.clone({ keepId: true }),
      target: graph,
      scaled: false,
      dndContainer: document.getElementById(this.dndContainer),
      validateNode: async (node, option) => {
        this.catchnode = node;
        this.dialogFormVisible = true;
        this.addnodeform.name4 = "";
        const test = () => {
          return new Promise(resolve => {
            this.resolveFn = resolve;
          });
        };
        return await test();
      }
    });
    this.drawedg();
    this.nodevent();
    this.getFlownode();
  }


};
</script>
<style>
.x6-widget-selection-box {
    border: none;
    box-shadow: none;
}

.x6-widget-selection-box {
    border: none !important;
}

.x6-widget-selection-marquee {
    border: none !important;
}

::-webkit-scrollbar-corner {
    background-color: transparent;
}
</style>

  